﻿using ROOT.CIMV2.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Management;
using System.Net.NetworkInformation;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using ROOT.CIMV2.Win32;

namespace Mac_Changger
{
    public partial class Form1 : Form
    {
        Random random = new Random();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
            Refresh.PerformClick();
        }

        private void GetAllAdapters()
        {
            AllAdapters.Items.Clear();

            SelectQuery query = new SelectQuery("Win32_NetworkAdapter");
            ManagementObjectSearcher search = new ManagementObjectSearcher(query);

            try
            {
                foreach (var nic in search.Get())
                {
                    NetworkAdapter adapter = new NetworkAdapter(nic);

                    if (string.IsNullOrEmpty(adapter.AdapterType) == false && adapter.AdapterType != "Tunnel" &&
                        adapter.ServiceName.Contains("tap") != true)
                        AllAdapters.Items.Add(adapter.Name);
                }
            }
            catch (Exception) { }

        }

        private void GetConnectedAdapters()
        {
            System.Management.ManagementClass managment = default(System.Management.ManagementClass);
            managment = new ManagementClass("Win32_NetworkAdapterConfiguration");
            try
            {
                foreach (var adapter in managment.GetInstances())
                {
                    if ((bool)adapter["IPEnabled"] == true)
                    {
                        Adapters.Items.Add(adapter["Caption"].ToString().Substring(11));
                    }
                }
            }
            catch (Exception) { }
        }

        private string GetMACAddress(string choosenAdapter)
        {
            System.Management.ManagementClass managment = default(System.Management.ManagementClass);
            managment = new ManagementClass("Win32_NetworkAdapterConfiguration");
            
            try{
                foreach (var adapter in managment.GetInstances())
                {
                    if ((bool)adapter["IPEnabled"] == true)
                    {
                        if (adapter["Caption"].ToString().Substring(11) == choosenAdapter)
                        {
                            return adapter["MacAddress"].ToString();
                        }
                    }
                }
            }
            catch (Exception) { }

            return "00:00:00:00:00:00";
        }

        private void Adapters_SelectedIndexChanged(object sender, EventArgs e)
        {
            CurrentMac.Text = GetMACAddress(Adapters.SelectedItem.ToString());
        }

        private string DoPadding(string value)
        {
            string padding = null;
            int i = 0;

            padding = value;
            if (value.Length< 4)
            {
                for (i = 1; i <= 4 - value.Length; i++)
                {
                    padding = "0" + padding;
                }
            }

            return padding;
        }

        private void Configure()
        {
            try
            {
                this.Enabled = false;
                DisEnableAdapter();
                Thread.Sleep(2000);
                EnableAdapter();
                MessageBox.Show("Your MAC Address has been changed.");
                this.Enabled = true;
                Refresh.PerformClick();
            }
            catch (Exception) { }

        }

        private bool EnableAdapter()
        {

            SelectQuery query = new SelectQuery("Win32_NetworkAdapter", "NetConnectionStatus=0");
            ManagementObjectSearcher search = new ManagementObjectSearcher(query);

            bool isenable=false;
            foreach (ManagementObject result in search.Get())
            {
                NetworkAdapter adapter = new NetworkAdapter(result);

                try
                {
                    if (adapter.Name.Equals(AllAdapters.SelectedItem.ToString()))
                    {
                        adapter.Enable();
                        isenable = true;
                        return true;
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    return false;
                }
            }

            if(!isenable)
                MessageBox.Show("You must enable the Adapter manually from\n"+
                    "Network and sharing center by changing adapter settings");
            return false;
            
        }

        private bool DisEnableAdapter()
        {
            SelectQuery query = new SelectQuery("Win32_NetworkAdapter", "NetConnectionStatus=2");
            ManagementObjectSearcher search = new ManagementObjectSearcher(query);
            try
            {
                foreach (ManagementObject result in search.Get())
                {
                    NetworkAdapter adapter = new NetworkAdapter(result);

                    if (adapter.Name.Equals(AllAdapters.SelectedItem.ToString()))
                    {
                        adapter.Disable();
                        return true;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            return false;
        }

        private string GetRoot(string Adapter)
        {
            Microsoft.Win32.RegistryKey regKey = null;
            int i = 0;

            try
            {
                while (true)
                {
                    string Root = "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
                    string subindex = DoPadding(i.ToString());
                    regKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(Root + subindex, true);

                    try
                    {
                        string cAdapter = regKey.GetValue("DriverDesc").ToString();
                        if (cAdapter == Adapter)
                        {
                            return Root + subindex;
                        }
                    }
                    catch
                    {
                        break;
                    }
                    i++;
                }
            }
            catch (Exception) { }
            return string.Empty;
        }

        private void OK_Click(object sender, EventArgs e)
        {
            if (IsReady() == false)
            {
                return;
            }
            Microsoft.Win32.RegistryKey regKey = null;
            string Addr = GetRoot(Adapters.SelectedItem.ToString());
            regKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(Addr, true);

            regKey.SetValue("NetworkAddress", NewMac.Text.Replace(":", ""));
            var test = regKey.GetValue("NetworkAddress");
            Configure();
        }

        private bool IsReady()
        {
            if (string.IsNullOrEmpty(NewMac.Text))
            {
                MessageBox.Show("You didn't enter a MAC Address");
                return false;
            }

            string mac = NewMac.Text.Replace(":", "");

            if (mac.Length != 12)
            {
                MessageBox.Show("A MAC Address must have a length of 12");
                return false;
            }

            try
            {
                if (string.IsNullOrEmpty(Adapters.SelectedItem.ToString()))
                {
                    MessageBox.Show("No Network Adapter selected");
                    return false;
                }
            }
            catch
            {
                MessageBox.Show("No Network Adapter selected");
                return false;
            }

            if (IsHex(mac) == false)
            {
                MessageBox.Show("MAC Address in wrong format");
                return false;
            }

            return true;
        }

        private bool IsHex(string text)
        {
            if (System.Text.RegularExpressions.Regex.IsMatch(text, @"\A\b[0-9a-fA-F]+\b\Z"))
                return true;
            else
                return false;
        }

        private void Reset_Click(object sender, EventArgs e)
        {

            try
            {
                if (string.IsNullOrEmpty(Adapters.SelectedItem.ToString()))
                {
                    MessageBox.Show("No Network Adapter selected");
                    return ;
                }
            }
            catch
            {
                MessageBox.Show("No Network Adapter selected");
                return ;
            }
           
            Microsoft.Win32.RegistryKey regKey = null;
            string Addr = GetRoot(Adapters.SelectedItem.ToString());
            regKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(Addr, true);

            try
            {
                regKey.DeleteValue("NetworkAddress");
            }
            catch
            {
            }
            Configure();

        }

        private void RandomMask_Click(object sender, EventArgs e)
        {
            NewMac.Text = GetRandomMacAddress();
        }

        private string GetRandomHexNumber(int digits)
        {
            byte[] buffer = new byte[digits / 2];
            random.NextBytes(buffer);
            string result = String.Concat(buffer.Select(x => x.ToString("X2")).ToArray());
            if (digits % 2 == 0)
                return result;
            return result + random.Next(16).ToString("X");
        }

        private string GetRandomMacAddress()
        {
            string randomHex = GetRandomHexNumber(12);
            string address = AddMask(randomHex);
            return address;
        }

        private string AddMask(string address)
        {
            string newAddress = "00:00:00:00:00:00";

            
            try
            {
                newAddress = Regex.Replace(address, ".{2}", "$0:");
                newAddress = newAddress.Remove(newAddress.Count() - 1, 1);
            }
            catch (Exception) { }

            return newAddress;
        }

        private void Refresh_Click(object sender, EventArgs e)
        {
            Adapters.Items.Clear();
            GetConnectedAdapters();
            GetAllAdapters();
            GetAllAdapters();
            if (Adapters.Items.Count > 0)
            {
                Adapters.SelectedIndex = 0;
                AllAdapters.SelectedIndex = AllAdapters.Items.IndexOf(Adapters.SelectedItem.ToString());

            }
            else
            {
                AllAdapters.SelectedIndex = 0;

            }
        }

        private void Disable_Click(object sender, EventArgs e)
        {
            if(DisEnableAdapter())
                MessageBox.Show("Network adapter disabled successfully!", " ", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void Enable_Click(object sender, EventArgs e)
        {
            if(EnableAdapter())
                MessageBox.Show("Network adapter Enabled Successfully", " ", MessageBoxButtons.OK, MessageBoxIcon.Information);
            
        }

        private void About_Click(object sender, EventArgs e)
        {
            MessageBox.Show(this.Text + ".\nBy Shukri Alyafey. \n© All rights reserved 2013.");
        }

    }
}
